/*
 * Copyright (c) 2014-2016 Alibaba Group. All rights reserved.
 * License-Identifier: Apache-2.0
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may
 * not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

#ifndef _IOTX_COMMON_HTTPCLIENT_H_
#define _IOTX_COMMON_HTTPCLIENT_H_

#include "iot_import.h"
#include "iot_export.h"
#include "utils_net.h"

#ifdef __cplusplus
extern "C" {
#endif

/**
 * @addtogroup HttpClient
 * @{
 * HttpClient API implements the client-side of HTTP/1.1. It provides base interfaces to execute an HTTP request on a given URL. It also supports HTTPS (HTTP over TLS) to provide secure communication.\n
 * @section HttpClient_Usage_Chapter How to use this module
 * In this release, MediaTek provides two types of APIs: high level APIs and low level APIs.\n
 * - \b The \b high \b level \b APIs
 *  - Enables to execute a single HTTP request on a given URL.
 *  - Call #httpclient_get(), #httpclient_post(), #httpclient_put() or #httpclient_delete() to get, post, put or delete and HTTP request.\n
 * - \b The \b low \b level \b APIs
 *  - Enables to execute more than one HTTP requests during a Keep-Alive connection. Keep-alive is the idea of using a single TCP connection to send and receive multiple HTTP requests/responses, as opposed to opening a new connection for every single request/response pair.
 *  - Step1: Call #httpclient_connect() to connect to a remote server.
 *  - Step2: Call #httpclient_send_request() to send an HTTP request to the server.
 *  - Step3: Call #httpclient_recv_response() to receive an HTTP response from the server.
 *  - Step4: Repeat Steps 2 and 3 to execute more requests.
 *  - Step5: Call #httpclient_close() to close the connection.
 *  - Sample code: Please refer to the example under <sdk_root>/project/mt7687_hdk/apps/http_client/http_client_keepalive folder.
 */

/** @defgroup httpclient_define Define
 * @{
 */
/** @brief   This macro defines the HTTP port.  */
#define HTTP_PORT   80

/** @brief   This macro defines the HTTPS port.  */
#define HTTPS_PORT 443
/**
 * @}
 */

/** @defgroup httpclient_enum Enum
 *  @{
 */
/** @brief   This enumeration defines the HTTP request type.  */
typedef enum {
    HTTPCLIENT_GET,
    HTTPCLIENT_POST,
    HTTPCLIENT_PUT,
    HTTPCLIENT_DELETE,
    HTTPCLIENT_HEAD
} HTTPCLIENT_REQUEST_TYPE;


/** @defgroup httpclient_struct Struct
 * @{
 */
/** @brief   This structure defines the httpclient_t structure.  */
typedef struct {
    int                 remote_port;    /**< HTTP or HTTPS port. */
    utils_network_t     net;
    int                 response_code;  /**< Response code. */
    char               *header;         /**< Custom header. */
    char               *auth_user;      /**< Username for basic authentication. */
    char               *auth_password;  /**< Password for basic authentication. */
} httpclient_t;

/** @brief   This structure defines the HTTP data structure.  */
typedef struct {
    bool    is_more;                /**< Indicates if more data needs to be retrieved. */
    bool    is_chunked;             /**< Response data is encoded in portions/chunks.*/
    int     retrieve_len;           /**< Content length to be retrieved. */
    int     response_content_len;   /**< Response content length. */
    int     post_buf_len;           /**< Post data length. */
    int     response_buf_len;       /**< Response buffer length. */
    char   *post_content_type;      /**< Content type of the post data. */
    char   *post_buf;               /**< User data to be posted. */
    char   *response_buf;           /**< Buffer to store the response data. */
} httpclient_data_t;


#if 0
 @brief            This function executes a POST request on a given URL. It blocks until completion.
 @param[in]        client is a pointer to the #httpclient_t.
 @param[in]        url is the URL to run the request.
 @param[in]        port is #HTTP_PORT or #HTTPS_PORT.
 @param[in, out]   client_data is a pointer to the #httpclient_data_t instance to collect the data returned by the request. It also contains the data to be posted.
 @return           Please refer to #HTTPCLIENT_RESULT.
 @par              HttpClient Post Example
 @code
                   char *url = "https://api.mediatek.com/mcs/v2/devices/D0n2yhrl/datapoints.csv";
                   char *header = "deviceKey:FZoo0S07CpwUHcrt\r\n";
                   char *content_type = "text/csv";
                   char *post_data = "1,,I am string!";
                   httpclient_t client = {0};
                   httpclient_data_t client_data = {0};
                   char *buf = NULL;
                   buf = pvPortMalloc(BUF_SIZE);
                   if (buf == NULL) {
                       HAL_Printf("Malloc failed.\r\n");
                       return;
                   }
                   memset(buf, 0, sizeof(buf));
                   client_data.response_buf = buf;  /* Sets a buffer to store the result. */
                   client_data.response_buf_len = BUF_SIZE;  /* Sets the buffer size. */
                   httpclient_set_custom_header(&client, header);  /* Sets the custom header if needed. */
                   client_data.post_buf = post_data;  /* Sets the user data to be posted. */
                   client_data.post_buf_len = strlen(post_data);  /* Sets the post data length. */
                   client_data.post_content_type = content_type;  /* Sets the content type. */
                   httpclient_post(&client, url, HTTPS_PORT, &client_data);
                   HAL_Printf("Data received: %s\r\n", client_data.response_buf);
 @endcode
#endif

int iotx_post(httpclient_t *client,
              const char *url,
              int port,
              const char *ca_crt,
              uint32_t timeout,
              httpclient_data_t *client_data);

int httpclient_common(httpclient_t *client, const char *url, int port, const char *ca_crt, int method,
                      uint32_t timeout_ms,
                      httpclient_data_t *client_data);

#ifdef __cplusplus
}
#endif

#endif /* __HTTPCLIENT_H__ */

